<?php

namespace app\home\controller;

use app\common\controller\Home;

//控制器 Controller
class Index extends Home
{
    //所有的控制器方法都不需要登录
    public $NoCheckLogin = ["*"];

    public function __construct()
    {

        // 继承底层构造函数
        parent::__construct();
        // 公共区域中加载模型，那么下面所有的方法中都可以使用这个模型
        $this->BusinessModel = model('Business.Business');

        // 课程模型
        $this->SubjectModel = model('Subject.Subject');
        // 课程章节
        $this->ChapterModel = model('Subject.Chapter');
        // 课程评论
        $this->CommentModel = model('Subject.Comment');
        // 课程订单
        $this->OrderModel = model('Subject.Order');
    }

    // ---------- 主页轮播图以及首页课程 ----------
    public function index()
    {
        // 首页界面数据获取
        // 首页轮播图数据
        $swiperList = $this->SubjectModel->order('createtime desc')->limit(5)->select();
        $list = $this->SubjectModel->order('id desc')->limit(8)->select();

        // 将数据组装，复制到view中（相当于js向html传送数据）
        $data = [
            'swiperList' => $swiperList,
            'list' => $list,
        ];
        // 赋值(传送)数据到view(模板、html)中去
        $this->assign($data);

        // 渲染一个模板页面
        return $this->view->fetch();
    }

    // ---------- 注册页逻辑 ----------
    public function register()
    {
        // 判断是否为POST请求
        if ($this->request->isPost()) {
            //接收手机号和密码
            // $mobile = isset($_POST['mobile']) ? trim($_POST['mobile']) : '';
            $mobile = $this->request->param('mobile', '', 'trim');
            $password = $this->request->param('password', '', 'trim');

            if (empty($password)) {
                $this->error('密码不能为空');
                exit;
            }


            //生成一个密码盐
            $salt = randstr();

            //加密密码
            $password = md5($password . $salt);

            //查询出云课堂的渠道来源的ID信息 数据库查询

            //查询整条数据
            // $source = model('common/Business/Source')->where(['name'=>['LIKE', "%云课堂%"]])->find();

            //组装数据
            $data = [
                'mobile' => $mobile,
                'nickname' => $mobile,
                'password' => $password,
                'salt' => $salt,
                'gender' => '0', //性别
                'deal' => '0', //成交状态
                'money' => '0', //余额
                'auth' => '0', //实名认证
            ];

            //只查询一个字段
            $data['sourceid'] = model('common/Business/Source')->where(['name' => ['LIKE', "%云课堂%"]])->value('id');

            // 插入到数据库（1、创建客户模型 2、新建验证器，手动创建）
            $result = $this->BusinessModel->validate('common/Business/Business')->save($data);
            // save 和 insert 都是插入方法 但是有区别：
            // save 可以自动插入时间戳字段，而且也支持validate验证器的验证 
            // insert 不会

            // $result 插入的返回结果，成功为1，失败为0
            if ($result === FALSE) {
                //失败
                $this->error($this->BusinessModel->getError());
                exit;
            } else {
                //注册
                $this->success('注册成功', url('home/index/login'));
                exit;
            }
        }

        // 渲染一个模板页面
        return $this->view->fetch();
    }

    // ---------- 登录页逻辑 ----------
    public function login()
    {
        //判断是否为微信浏览器访问
        if(Wechat())
        {
            $openid = session('openid') ? session('openid') : '';

            if(empty($openid))
            {
                $this->redirect(url('home/wechat/oauth'));
                exit;
            }
        }

        //判断是否是Post请求
        if($this->request->isPost())
        {
            //获取数据
            $mobile = $this->request->param('mobile', '', 'trim');
            $password = $this->request->param('password', '', 'trim');

            //根据手机号来查询数据存不存在
            $business = $this->BusinessModel->where(['mobile' => $mobile])->find();

            // 用户不存在
            if(!$business)
            {
                $this->error('用户不存在');
                exit;
            }

            //数据打印
            // var_dump($business->toArray());
            // exit;

            //验证密码
            $salt = $business['salt'];
            $password = md5($password.$salt);

            if($password != $business['password'])
            {
                $this->error('密码不正确');
                exit;
            }

            // 当资料中的openid为空的时候 就更新 
            if(empty($business['openid']))
            {
                //判断是否有openid
                $openid = session('openid') ? session('openid') : '';

                if(!empty($openid))
                {
                    $update = [
                        'id' => $business['id'],
                        'openid' => $openid
                    ];

                    $result = $this->BusinessModel->isUpdate(true)->save($update);

                    if($result === FALSE)
                    {
                        $this->error('授权绑定用户失败');
                        exit;
                    }
                }
            }

            //保存cookie信息
            $cookie = [
                'id' => $business['id'],
                'mobile' => $business['mobile'],
            ];

            //存放cookie 关闭浏览器之后自动销毁
            cookie('business', $cookie);

            //跳转会员中心
            $this->success('登录成功', url('home/business/index'));
            exit;
        }

        // 访问地址：www.fast.com/index.php/home/index/register
        //渲染模板 application/home/view/Index/register.html
        return $this->view->fetch();
    }

    // ---------- 退出登录逻辑 ----------
    public function logout()
    {
        //清除cookie
        cookie('business', null);
        $this->success('退出成功', url('home/index/login'));
        exit;
    }

    // ---------- 详情页 ----------
    public function info()
    {
        // 通过get的课程id，渠道课程表中查询具体课程数据
        $pid = $this->request->param('pid', 0, 'trim');

        // 先判断课程是否在数据库中存在
        $subject = $this->SubjectModel->find($pid);

        if (!$subject) {
            $this->error('课程不存在');
            exit;
        }

        // 课程章节
        $chapter = $this->ChapterModel->where(['subid' => $pid])->select();

        // 课程评论
        $comment = $this->CommentModel->with(['business'])->where(['subid' => $pid])->limit(8)->select();

        // 需要显示点赞，就需要判断当前用户是否登录，再去数据库中找数据
        // 看看当前登录用户是否评论过这个课程
        // 判断是否有登录

        // 获取用户信息 CheckLogin(); 为公共模块下的 common/controller/Home.php 用户控制器函数
        $business = $this->CheckLogin(false);

        if ($business) {
            $busid = $business['id'];
            $likes = $subject['likes'];
            //将点赞人的id转换为数组
            if (empty($likes)) {
                $likes = [];
            } else {
                $likes = explode(',', $likes);
            }

            //判断当前登录的人id 在不在 点赞的数组中 如果在就说明点过赞
            if (in_array($busid, $likes)) {
                $subject['like_status'] = true;
            } else {
                $subject['like_status'] = false;
            }
        } else {
            //没有登录
            $subject['like_status'] = false;
        }

        $this->assign([
            'subject' => $subject,
            'chapter' => $chapter,
            'comment' => $comment,
        ]);

        return $this->view->fetch();
    }

    // ---------- 搜索页面 ----------
    public function search()
    {
        //先判断是否有ajax请求过来
        if ($this->request->isAjax()) {
            //接收参数
            $page = $this->request->param('page', 1, 'trim');
            $limit = $this->request->param('limit', 10, 'trim');
            $search = $this->request->param('search', '', 'trim');

            $where = [];

            if (!empty($search)) {
                //模糊查询
                $where['title'] = ['LIKE', "%$search%"];
            }

            //查询数据总数
            $count = $this->SubjectModel->where($where)->count();

            //偏移量
            $start = ($page - 1) * $limit;

            $list = $this->SubjectModel
                ->with(['category'])
                ->where($where)
                ->order('createtime desc')
                ->limit($start, $limit)
                ->select();

            $data = [
                'count' => $count,
                'list' => $list
            ];

            if (empty($list)) {
                $this->error('暂无更多数据');
                exit;
            } else {
                $this->success('成功返回数据', null, $data);
                exit;
            }
        }


        return $this->view->fetch();
    }

    // ---------- 点赞 ----------
    public function like()
    {
        if ($this->request->isAjax()) {
            //接收参数
            $subid = $this->request->param('subid', 0, 'trim');
            $status = $this->request->param('status', '', 'trim');

            if (!in_array($status, ['add', 'remove'])) {
                $this->error('点赞状态有问题');
                exit;
            }

            //判断是否有登录
            $business = $this->CheckLogin(false);

            if (!$business) {
                $this->error('请登录');
                exit;
            }

            //判断课程是否存在
            $subject = $this->SubjectModel->where(['id' => $subid])->find();

            if (!$subject) {
                $this->error('课程不存在');
                exit;
            }

            $likes = empty($subject['likes']) ? [] : explode(',', $subject['likes']);

            //如果在 就说明点过赞 要取消点赞
            if (in_array($business['id'], $likes)) {
                $pos = array_search($business['id'], $likes);

                //删除变量元素
                unset($likes[$pos]);
            } else {
                //不在，就说明没点过赞，要点赞
                $likes[] = $business['id'];
            }

            //会怕存在遗漏 去重 保证唯一性
            $likes = array_unique($likes);
            $likes = implode(',', $likes);

            //组装数据更新
            $data = [
                'id' => $subid,
                'likes' => $likes
            ];

            $result = $this->SubjectModel->isUpdate(true)->save($data);

            if ($result === FALSE) {
                $msg = $status == "add" ? "点赞失败" : "取消点赞失败";
                $this->error($msg);
                exit;
            } else {
                $msg = $status == "add" ? "点赞成功" : "取消点赞成功";
                $this->success($msg);
                exit;
            }
        }
    }

    // ---------- 所有评论 ----------
    public function comment_list()
    {

        //先判断是否有ajax请求过来
        if ($this->request->isAjax()) {

            //接收 课程id
            $subid = $this->request->param('subid', 0, 'trim');

            // 先判断课程是否在数据库中存在
            $subject = $this->SubjectModel->find($subid);

            if (!$subject) {
                $this->error('课程不存在');
                exit;
            }
            // 根据课程id在评论表中查询该课程的所有评论信息 （时间倒序）
            $comment = $this->CommentModel
                ->with(['business'])   // 连接用户信息表，同时可以查询出用户的相关信息
                ->where(['subid' => $subid])
                ->order('createtime desc')
                ->select();
            // 抽离出所有评论数据
            $comList = collection($comment)->toArray();

            // 统计当前课程的所有评论数据
            $count = count($comList);

            $data = [
                'count' => $count,
                'list' => $comList,
            ];

            if (empty($comList)) {
                $this->error('暂无更多数据');
                exit;
            } else {
                $this->success('成功返回数据', null, $data);
                exit;
            }
        }

        return $this->view->fetch();
    }



    // ---------- 点击播放（购买课程）功能 ----------
    // 订单验证(点击播放)
    public function play()
    {
        //判断是否是ajax请求
        if ($this->request->isAjax()) {
            // 课程id
            $subid = $this->request->param('subid', 0, 'trim');
            // 章节id
            $cid = $this->request->param('cid', 0, 'trim');


            // ------ 课程信息效验 ------
            // 判断课程是否存在
            $subject = $this->SubjectModel->find($subid);
            // 课程不存在
            if (!$subject) {
                $this->error('课程不存在');
                exit;
            }



            // ------ 章节信息效验 ------
            // 判断章节是否存在
            $chapter = $this->ChapterModel->find($cid);
            // 章节不存在
            if (!$chapter) {
                //根据课程找出这个课程的第一个章节
                $chapter = $this->ChapterModel->where(['subid' => $subid])->order('id asc')->find();

                if (empty($chapter)) {
                    $this->error('该课程无章节');
                    exit;
                }
            }

            // ------ 用户信息效验 ------
            // 判断是否有登录
            $business = $this->CheckLogin(false);
            if (!$business) {
                $this->error('请先登录');
                exit;
            }
            // 查询当前用户是否有购买过课程
            $where = [
                'busid' => $business['id'],
                'subid' => $subid
            ];
            $order = $this->OrderModel->where($where)->find();

            //订单不存在，就说明没有买过课程
            if (!$order) {
                $this->success('请先购买课程', null, ['status' => 'buy']);
                exit;
            } else {
                $this->success('已购买', null, $chapter);
                exit;
            }
        }
    }

    public function buy()
    {
        if($this->request->isAjax())
        {
            $subid = $this->request->param('subid', 0, 'trim');

            //判断课程是否存在
            $subject = $this->SubjectModel->find($subid);

            if(!$subject)
            {
                $this->error('课程不存在');
                exit;
            }

            //判断是否有登录
            $business = $this->CheckLogin(false);
            if(!$business)
            {
                $this->error('请先登录');
                exit;
            }

            //查询当前用户是否有购买过课程
            $where = [
                'busid' => $business['id'],
                'subid' => $subid
            ];

            $order = $this->OrderModel->where($where)->find();

            //判断是否有重复购买课程
            if($order)
            {
                $this->error('您已购买过该课程');
                exit;
            }

            //subject_order 课程订单 插入
            // business 用户余额 更新
            // business_record 消费记录 插入

            //加载模型
            $OrderModel = model('Subject.Order');
            $BusinessModel = model('Business.Business');
            $RecordModel = model('Business.Record');

            //开启事务
            $OrderModel->startTrans();
            $BusinessModel->startTrans();
            $RecordModel->startTrans();

            //判断用户余额是否充足
            $money = empty($business['money']) ? 0 : $business['money'];
            $price = empty($subject['price']) ? -1 : $subject['price'];

            if($price < 0)
            {
                $this->error('课程的价格有误，无法进行购买');
                exit;
            }

            //两个高精度的浮点数相减
            $UpdateMoney = bcsub($money, $price, 2);

            //用户余额不足
            if($UpdateMoney < 0)
            {
                $this->error('您的余额不足，请先充足');
                exit;
            }

            //生成课程的订单号
            $code = build_code('SUB');

            //组装订单数据
            $OrderData = [
                'subid' => $subid,
                'busid' => $business['id'],
                'total' => $price,
                'code' => $code,
            ];

            //执行插入
            $OrderStatus = $OrderModel->validate('common/Subject/Order')->save($OrderData);

            if($OrderStatus === FALSE)
            {
                $this->error($OrderModel->getError());
                exit;
            }

            //更新用户余额表
            $BusinessData = [
                'id' => $business['id'],
                'money' => $UpdateMoney
            ];

            //验证器
            $validate = [
                [
                    'money' => 'require|number|>=:0'
                ],
                [
                    'money.require' => '余额未知',
                    'money.number' => '余额必须是数字',
                    'money.>=' => '余额必须是大于等于0元',
                ]
            ];

            $BusinessStatus = $BusinessModel->validate(...$validate)->isUpdate(true)->save($BusinessData);

            if($BusinessStatus === FALSE)
            {
                $OrderModel->rollback();
                $this->error($BusinessModel->getError());
                exit;
            }

            $title = $subject['title'];
            // $content = "您购买了课程【{$title}】:花费了：￥ $price 元";

            $content = "您购买了课程【{$title}】";

            //插入消费记录表
            $RecordData = [
                'total' => -$price,
                'busid' => $business['id'],
                'content' => $content
            ];

            $RecordStatus = $RecordModel->validate('common/Business/Record')->save($RecordData);

            if($RecordStatus === FALSE)
            {
                $BusinessModel->rollback();
                $OrderModel->rollback();
                $this->error($RecordModel->getError());
                exit;
            }

            //总的判断
            if($OrderStatus === FALSE || $BusinessStatus === FALSE || $RecordStatus === FALSE)
            {
                $RecordModel->rollback();
                $BusinessModel->rollback();
                $OrderModel->rollback();
                $this->error('购买课程失败');
                exit;
            }
            
            //提交事务
            $OrderModel->commit();
            $BusinessModel->commit();
            $RecordModel->commit();

           //发送模板消息
           if(!empty($business['openid']))
           {
               //组装数据
               $data = [
                   'touser' => $business['openid'],
                   'template_id' => 'kFRch4ffmgddh2Lg0IFXz4bhHClFGN6EmBOLb24WW7Q',
                   'url' => url('home/index/info', ['pid' => $subid], true, true),
                   'data' => [
                       'time' => date("Y-m-d H:i", time()),
                       'money' => $price,
                       'name' => $title
                   ]
               ];

               $WechatController = new \app\home\controller\Wechat();
               
               $WechatController->template($data);
           }

           $this->success('购买课程成功');
           exit;

        }
    }
}
